package com.liush.srb.core.service.impl;

import com.liush.srb.core.pojo.entity.Lend;
import com.liush.srb.core.pojo.entity.LendItemReturn;
import com.liush.srb.core.pojo.entity.LendReturn;
import com.liush.srb.core.mapper.LendReturnMapper;
import com.liush.srb.core.pojo.entity.UserInfo;
import com.liush.srb.core.service.LendReturnService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liush.srb.core.util.LendNoUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 还款记录表 服务实现类
 * </p>
 *
 * @author liush
 * @since 2023-03-25
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class LendReturnServiceImpl extends ServiceImpl<LendReturnMapper, LendReturn> implements LendReturnService {

    public List<LendReturn> saveLendReturns(Lend lend, UserInfo userInfo) {
        // 根据标的期数 生成期数个还款计划，每个还款计划数据存到 lend_return表中
        List<LendReturn> lendReturns = new ArrayList<>();
        for (Integer i = 1; i <= lend.getPeriod(); i++) {
            LendReturn lendReturn = new LendReturn();
            lendReturn.setLendId(lend.getId());
            lendReturn.setBorrowInfoId(lend.getBorrowInfoId());
            lendReturn.setReturnNo(LendNoUtils.getReturnNo());
            lendReturn.setUserId(userInfo.getId());//借款人id
            lendReturn.setAmount(lend.getAmount());//申请的借款金额
            lendReturn.setBaseAmount(lend.getInvestAmount());//募资到的计算利息的金额
            lendReturn.setCurrentPeriod(i);
            lendReturn.setLendYearRate(lend.getLendYearRate());//年化率是*100的值
            lendReturn.setReturnMethod(lend.getReturnMethod());
            //还款方式不一样 计算利息本金方式不一样
            //一次还本付息： 除了最后一期 需要还本金利息 其他的都是0
            //由于 计算本金利息时 利率采用了四舍五入方式处理
            // 一个标的有多个投资项 多个投资项本期 回款本金相加 可能会和还款本金不一样
            // 还款本金应该等于=  多个投资项本期回款本金之和
            // 还款利息应该等于=  多个投资项本期回款利息之和
            // 还款本息应该等于=  多个投资项本期回款本息之和
            lendReturn.setFee(new BigDecimal(0));
            lendReturn.setReturnDate(new DateTime(lend.getLendStartDate()).plusMonths(i).toDate());//本期的还款日：第一期 是计息日+1
            lendReturn.setRealReturnTime(null);//本期实际还款日
            lendReturn.setOverdue(null);//还款是否逾期
            lendReturn.setOverdueTotal(new BigDecimal(0));//逾期费用
            lendReturn.setStatus(0);
            lendReturn.setLast(i == lend.getPeriod());//是否是最后一期还款
            lendReturns.add(lendReturn);
        }
        //批量保存还款计划： 批量保存时 每个LendReturn会生成雪花算法的id
        this.saveBatch(lendReturns);
        return lendReturns;
    }

    public void updateLendReturns(List<LendReturn> lendReturns, List<LendItemReturn> lendItemReturns) {
        //遍历还款计划集合
        lendReturns.forEach(lendReturn -> {
            //查找本期的回款计划集合
            //
            /*
                    标的：1
                        还款计划：
                            1/2/3/4/5/6
                        回款计划：
                            A
                                投资记录1    每期回款计划对应一个还款计划
                                    1/2/3/4/5/6

                            B
                                投资记录1    每期回款计划对应一个还款计划
                                     1/2/3/4/5/6
             */
            List<LendItemReturn> currentLendItemReturns = lendItemReturns.stream().filter(lendItemReturn ->
                            lendItemReturn.getCurrentPeriod() == lendReturn.getCurrentPeriod())
                    .collect(Collectors.toList());
            BigDecimal principal = currentLendItemReturns.stream().map(LendItemReturn::getPrincipal).reduce((a, b) -> a.add(b)).get();
            BigDecimal interest = currentLendItemReturns.stream().map(LendItemReturn::getInterest).reduce((a, b) -> a.add(b)).get();
            BigDecimal pi = currentLendItemReturns.stream().map(LendItemReturn::getTotal).reduce((a, b) -> a.add(b)).get();
            lendReturn.setPrincipal(principal);
            lendReturn.setInterest(interest);
            lendReturn.setTotal(pi);
        });
        //更新还款计划的本金利息
        this.updateBatchById(lendReturns);
    }

}
